/**
  ******************************************************************************
  * @file    iap_uart.c 
  * @author  iron
  * @date 	 2018-07-09
  * @version v1.0
  * @brief   iap uart rx/tx data interface
  */

/** @addtogroup IAP_GROUP
  * @{
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "iap_uart.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define IAP_UART_DEFAULT_TIMEOUT	100

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
//extern UART_HandleTypeDef huart3;
//extern UART_HandleTypeDef huart6;

static UART_HandleTypeDef *iap_uart_handler = NULL;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  iap uart init
  * @retval receive data length
  */
int iap_uart_init(void)
{
	iap_uart_handler = &huart1;
	
	return 0;
}

/**
  * @brief  iap uart receive data
  * @param  p_data
  * @param  size
  * @param  timeout
  * @retval receive data length
  */
int iap_uart_recv(uint8_t *p_data, uint32_t size, uint32_t timeout)
{
	if (iap_uart_handler == NULL || p_data == NULL || size == 0)
	{
		return HAL_ERROR;
	}
	
	return HAL_UART_Receive(iap_uart_handler, p_data, size, timeout);
}

/**
  * @brief  iap uart receive data
  * @param  p_data
  * @param  length
  * @param  timeout
  * @retval receive data length
  */
int iap_uart_send(uint8_t *p_data, uint32_t length, uint32_t timeout)
{
	if (iap_uart_handler == NULL || p_data == NULL || length == 0)
	{
		return HAL_ERROR;
	}
	
	return HAL_UART_Transmit(iap_uart_handler, p_data, length, timeout);
}

/**
  * @brief  iap uart receive data
  * @param  p_data
  * @param  size
  * @param  timeout
	* @retval send data length
  *				0: send data error or timeout.
	*				1: send data ok
  */
int iap_uart_getc(uint32_t timeout)
{
	uint8_t chr = 0xFF; // OF(-1)
	
	if (iap_uart_handler == NULL)
	{
		return 0;
	}
	
  if ( iap_uart_handler->gState == HAL_UART_STATE_TIMEOUT )
  {
    iap_uart_handler->gState = HAL_UART_STATE_READY;
  }
	
  if (HAL_UART_Receive(iap_uart_handler, &chr, 1, timeout) == HAL_OK)
	{
		return chr;
	}
	
	return (-1); // EOF
}

/**
  * @brief  iap uart receive data
  * @param  p_data
  * @param  size
  * @param  timeout
  * @retval return status
	*				0: error or timeout
	*				1: getc ok
  */
int iap_uart_putc(uint8_t chr)
{
	if (iap_uart_handler == NULL)
	{
		return HAL_ERROR;
	}
	
  if (iap_uart_handler->gState == HAL_UART_STATE_TIMEOUT)
  {
    iap_uart_handler->gState = HAL_UART_STATE_READY;
  }
	
  return HAL_UART_Transmit(iap_uart_handler, &chr, 1, IAP_UART_DEFAULT_TIMEOUT);
}

/**
  * @brief  flushes the UART rx data
  * @retval receive data length
  */
void iap_uart_rx_flush(void)
{
	if (iap_uart_handler != NULL)
	{
		__HAL_UART_FLUSH_DRREGISTER(iap_uart_handler);
	}
}

/**
  * @brief  Print a string on the HyperTerminal
  * @param  p_string: The string to be printed
  * @retval None
  */
void iap_uart_send_str(uint8_t *p_string)
{
  uint16_t length = 0;

  while (p_string[length] != '\0')
  {
    length++;
  }
	
  HAL_UART_Transmit(iap_uart_handler, p_string, length, 100);
}

/**
  * @}
  */

/*******************(C)COPYRIGHT 2018 Iron *****END OF FILE*******************/
